package com.knowledgegraph.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.knowledgegraph.entity.EntityType;
import com.knowledgegraph.mapper.EntityTypeMapper;
import com.knowledgegraph.service.EntityTypeService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * 实体类型服务实现类
 * 
 * @author system
 * @since 2024-01-01
 */
@Slf4j
@Service
public class EntityTypeServiceImpl extends ServiceImpl<EntityTypeMapper, EntityType> implements EntityTypeService {

    @Override
    public IPage<EntityType> getEntityTypesWithPagination(Page<EntityType> page, Map<String, Object> queryParams) {
        QueryWrapper<EntityType> queryWrapper = new QueryWrapper<>();
        
        // 搜索条件
        String searchText = (String) queryParams.get("searchText");
        if (StringUtils.hasText(searchText)) {
            queryWrapper.and(wrapper -> wrapper
                .like("type_name", searchText)
                .or()
                .like("type_code", searchText)
                .or()
                .like("description", searchText)
            );
        }
        
        // 启用状态筛选
        Boolean enabled = (Boolean) queryParams.get("enabled");
        if (enabled != null) {
            queryWrapper.eq("enabled", enabled);
        }
        
        // 按排序序号和创建时间排序
        queryWrapper.orderByAsc("sort_order").orderByDesc("create_time");
        
        return this.page(page, queryWrapper);
    }

    @Override
    public List<EntityType> getEnabledEntityTypes() {
        return baseMapper.selectEnabledTypes();
    }

    @Override
    public List<EntityType> getUserEntityTypes(Long currentUserId) {
        return baseMapper.selectUserEntityTypes(currentUserId);
    }

    @Override
    public boolean createEntityType(EntityType entityType, Long userId) {
        try {
            // 检查类型代码是否已存在
            if (isTypeCodeExists(entityType.getTypeCode(), null)) {
                throw new RuntimeException("类型代码已存在");
            }
            
            entityType.setCreatorId(userId);
            entityType.setCreateTime(LocalDateTime.now());
            entityType.setUpdateTime(LocalDateTime.now());
            entityType.setDeleted(0);
            
            // 如果没有设置启用状态，默认启用
            if (entityType.getEnabled() == null) {
                entityType.setEnabled(true);
            }
            
            // 如果没有设置排序序号，设置为最大值+1
            if (entityType.getSortOrder() == null) {
                QueryWrapper<EntityType> wrapper = new QueryWrapper<>();
                wrapper.select("MAX(sort_order) as maxOrder");
                EntityType maxOrderType = this.getOne(wrapper);
                int maxOrder = maxOrderType != null && maxOrderType.getSortOrder() != null ? 
                    maxOrderType.getSortOrder() : 0;
                entityType.setSortOrder(maxOrder + 1);
            }
            
            return this.save(entityType);
        } catch (Exception e) {
            log.error("创建实体类型失败", e);
            throw new RuntimeException("创建实体类型失败: " + e.getMessage());
        }
    }

    @Override
    public boolean updateEntityType(EntityType entityType, Long userId) {
        try {
            // 检查类型代码是否已存在（排除当前记录）
            if (isTypeCodeExists(entityType.getTypeCode(), entityType.getId())) {
                throw new RuntimeException("类型代码已存在");
            }
            
            entityType.setUpdateTime(LocalDateTime.now());
            return this.updateById(entityType);
        } catch (Exception e) {
            log.error("更新实体类型失败", e);
            throw new RuntimeException("更新实体类型失败: " + e.getMessage());
        }
    }

    @Override
    public boolean deleteEntityType(Long id, Long userId) {
        try {
            // 检查是否有实体使用了这个类型
            // TODO: 添加检查逻辑，如果有实体使用了这个类型，不允许删除
            
            return this.removeById(id);
        } catch (Exception e) {
            log.error("删除实体类型失败", e);
            throw new RuntimeException("删除实体类型失败: " + e.getMessage());
        }
    }

    @Override
    public boolean batchDeleteEntityTypes(List<Long> ids, Long userId) {
        try {
            // 检查是否有实体使用了这些类型
            // TODO: 添加检查逻辑
            
            return this.removeByIds(ids);
        } catch (Exception e) {
            log.error("批量删除实体类型失败", e);
            throw new RuntimeException("批量删除实体类型失败: " + e.getMessage());
        }
    }

    @Override
    public boolean isTypeCodeExists(String typeCode, Long excludeId) {
        Long excludeIdValue = excludeId != null ? excludeId : -1L;
        return baseMapper.countByTypeCode(typeCode, excludeIdValue) > 0;
    }

    @Override
    public EntityType getByTypeCode(String typeCode) {
        return baseMapper.selectByTypeCode(typeCode);
    }

    @Override
    public boolean updateSortOrder(Long id, Integer sortOrder) {
        try {
            EntityType entityType = new EntityType();
            entityType.setId(id);
            entityType.setSortOrder(sortOrder);
            entityType.setUpdateTime(LocalDateTime.now());
            return this.updateById(entityType);
        } catch (Exception e) {
            log.error("更新排序序号失败", e);
            throw new RuntimeException("更新排序序号失败: " + e.getMessage());
        }
    }

    @Override
    public boolean toggleEnabled(Long id, Boolean enabled) {
        try {
            EntityType entityType = new EntityType();
            entityType.setId(id);
            entityType.setEnabled(enabled);
            entityType.setUpdateTime(LocalDateTime.now());
            return this.updateById(entityType);
        } catch (Exception e) {
            log.error("切换启用状态失败", e);
            throw new RuntimeException("切换启用状态失败: " + e.getMessage());
        }
    }

    @Override
    public boolean existsByTypeCode(String typeCode, Long excludeId) {
        return isTypeCodeExists(typeCode, excludeId);
    }
}
